This example shows how to get all trades (ticks) from the last trading day for Statoil ASA (STL). Ntfdl uses free and accessible data from the norwegian broker http://www.netfonds.no
In [1]:
%matplotlib inline
%pylab inline --no-import-all
pylab.rcParams['figure.figsize'] = (18, 10)
Import the downloader dl from ntfdl
In [2]:
from ntfdl import Dl
import pandas as pd
import talib
from matplotlib.finance import candlestick_ohlc
import matplotlib.dates as mdates
We instantiate the dl class with:
In [3]:
stl = Dl('STL', exchange='OSE', day='today', download=True)
In [4]:
# If download=False then you need to call dl.get_trades()
#trades = stl.get_trades()
In [5]:
# Calculate vwap
stl.vwap()
Since this is a pandas dataframe, all pandas functionality is exposed through dl.get_trades()
In [6]:
stl.trades.tail(5)
Out[6]:
In [7]:
stl.trades.price.max()
Out[7]:
In [8]:
stl.trades.price.std()
Out[8]:
Plotting pandas is also easy
In [9]:
fig, ax = plt.subplots()
# Plot price
stl.trades.price.plot(drawstyle='steps')
# Plot vwap
#stl.trades.price.plot(color='r')
# Adding axis right hand side
ax.tick_params(labeltop=False, labelright=True)
# Annotate last quote
xmin, xmax = ax.get_xlim()
plt.annotate(stl.trades.iloc[-1].price, xy=(1, stl.trades.iloc[-1].price), xytext=(0, 0), \
xycoords=('axes fraction', 'data'), textcoords='offset points', backgroundcolor='k', color='w')
ax.plot(xmax, stl.trades.iloc[-1].price, '<k', markersize=18, markeredgecolor='k')
plt.grid()
plt.title("Statoil ASA (STL.OSE)")
Out[9]:
You can easily resample the trade data yourself using pandas resample, but dl.get_ohlcv() will make it easier. dl.get_ohlcv() takes two parameters:
Note that volume always is included.
In [10]:
ohlcv = stl.get_ohlcv(interval='5min')
dl.get_ohlcv() also returns a Pandas dataframe, hence all Pandas functionality is available as well.
In [11]:
ohlcv.tail()
Out[11]:
In [12]:
def plot_candles(pricing, title=None,
volume_bars=False,
color_function=None,
overlays=None,
technicals=None,
technicals_titles=None):
def default_color(index, open, close, low, high):
return 'r' if open[index] > close[index] else 'g'
color_function = color_function or default_color
overlays = overlays or []
technicals = technicals or []
technicals_titles = technicals_titles or []
open = pricing['open']
close = pricing['close']
low = pricing['low']
high = pricing['high']
oc_min = pd.concat([open, close], axis=1).min(axis=1)
oc_max = pd.concat([open, close], axis=1).max(axis=1)
subplot_count = 1
if volume_bars:
subplot_count = 2
if technicals:
subplot_count += len(technicals)
if subplot_count == 1:
fig, ax1 = plt.subplots(1, 1)
else:
ratios = np.insert(np.full(subplot_count - 1, 1), 0, 3)
fig, subplots = plt.subplots(subplot_count, 1, sharex=True, gridspec_kw={'height_ratios': ratios})
ax1 = subplots[0]
if title:
ax1.set_title(title)
x = np.arange(len(pricing))
candle_colors = [color_function(i, open, close, low, high) for i in x]
candles = ax1.bar(x, oc_max-oc_min, bottom=oc_min, color=candle_colors, linewidth=0)
lines = ax1.vlines(x, low, high, color=candle_colors, linewidth=1)
ax1.xaxis.grid(False)
ax1.xaxis.set_tick_params(which='major', length=3.0, direction='in', top='off')
# Assume minute frequency if first two bars are in the same day.
frequency = 'minute' if (pricing.index[1] - pricing.index[0]).days == 0 else 'day'
time_format = '%d-%m-%Y'
if frequency == 'minute':
time_format = '%H:%M'
# Set X axis tick labels.
plt.xticks(x, [date.strftime(time_format) for date in pricing.index], rotation='vertical')
for overlay in overlays:
ax1.plot(x, overlay)
# Plot volume bars if needed
if volume_bars:
ax2 = subplots[1]
volume = pricing['volume']
volume_scale = None
scaled_volume = volume
if volume.max() > 1000000:
volume_scale = 'M'
scaled_volume = volume / 1000000
elif volume.max() > 1000:
volume_scale = 'K'
scaled_volume = volume / 1000
ax2.bar(x, scaled_volume, color=candle_colors)
volume_title = 'Volume'
if volume_scale:
volume_title = 'Volume (%s)' % volume_scale
ax2.set_title(volume_title)
ax2.xaxis.grid(False)
# Plot additional technical indicators
for (i, technical) in enumerate(technicals):
ax = subplots[i - len(technicals)] # Technical indicator plots are shown last
ax.plot(x, technical)
if i < len(technicals_titles):
ax.set_title(technicals_titles[i])
In [13]:
upper, middle, lower = talib.BBANDS(ohlcv['close'].as_matrix())
plot_candles(ohlcv, title='Statoil ASA 2017-10-23 [STL.OSE]',volume_bars=True, overlays=[upper, middle, lower])
In [14]:
import matplotlib.ticker as mplticker
from matplotlib.dates import date2num
from matplotlib.finance import candlestick_ohlc
fig, ax = plt.subplots(nrows=1, ncols=1, sharex=True, figsize=(18,10))
ax.xaxis.set_major_locator(mplticker.MaxNLocator(6))
#Convert to integer, not date...
ohlcv['time'] = ohlcv.index.astype(np.int64) // 10**9
xdate = ohlcv['time'] #[datetime.fromtimestamp(i) for i in ohlc['time']]
def mydate(x,pos):
try:
return xdate[int(x)]
except IndexError:
return ''
ax.xaxis.set_major_formatter(mplticker.FuncFormatter(mydate))
ax.tick_params(labeltop=False, labelright=True)
fig.autofmt_xdate()
fig.tight_layout()
tuples = [tuple(x) for x in ohlcv[['time','open','high','low','close']].values]
candlestick_ohlc(ax, tuples, colorup='g')
plt.show()
In [15]:
positions = stl.get_positions()
In [16]:
positions.tail(5)
Out[16]:
In [17]:
fig, ax = plt.subplots()
ax.tick_params(labeltop=False, labelright=True)
positions.bid.plot(drawstyle='steps', color='b')
positions.ask.plot(drawstyle='steps', color='g')
plt.title("Intraday best bid vs best ask")
plt.grid()
In [18]:
brokers = stl.get_broker_stats()
In [19]:
brokers.tail()
Out[19]:
In [20]:
brokers['sold'] = -1*brokers['sold']
brokers[['total']].plot(kind='barh', color=brokers['positive'].map({True: 'g', False: 'r'}))
plt.yticks( range(brokers.total.count()), brokers.broker)
plt.show()
In [21]:
brokers[['sold', 'bought']].plot(kind='barh', color=['r', 'g'])
plt.yticks( range(brokers.total.count()), brokers.broker)
#ax1.text(0, 0, stock_sell_buy['broker'], horizontalalignment=align, verticalalignment='center', color=clr, weight='bold')
plt.show()